﻿using System;
using System.ServiceModel.DomainServices.Client;
using System.ServiceModel.DomainServices.Client.ApplicationServices;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using Falafel.Assets.Resources;
using Falafel.Controls.Dialogs;
using Falafel.Services;
using TLCMWP.Services;

namespace Falafel
{
    public partial class App
    {
        private BusyIndicator _progressIndicator;
        public event EventHandler UserLoaded;

        public App()
        {
            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
            // This will enable you to bind controls in XAML files to WebContext.Current
            // properties
            //this.Resources.Add("WebContext", WebContext.Current);

            // This will automatically authenticate a user when using windows authentication
            // or when the user chose "Keep me signed in" on a previous login attempt
            WebContext.Current.Authentication.LoadUser(Application_UserLoaded, null);

            // Show some UI to the user while LoadUser is in progress
            InitializeRootVisual();
        }

        /// <summary>
        ///     Invoked when the <see cref="LoadUserOperation"/> completes. Use this
        ///     event handler to switch from the "loading UI" you created in
        ///     <see cref="InitializeRootVisual"/> to the "application UI"
        /// </summary>
        private void Application_UserLoaded(LoadUserOperation operation)
        {
            _progressIndicator.IsBusy = false;

            // Raise an event that the user is loaded
            if (UserLoaded != null)
                UserLoaded(this, new EventArgs());
        }

        /// <summary>
        ///     Initializes the <see cref="Application.RootVisual"/> property. The
        ///     initial UI will be displayed before the LoadUser operation has completed
        ///     (The LoadUser operation will cause user to be logged automatically if
        ///     using windows authentication or if the user had selected the "keep
        ///     me signed in" option on a previous login).
        /// </summary>
        protected virtual void InitializeRootVisual()
        {
            _progressIndicator = new BusyIndicator();
            _progressIndicator.Content = new MainPage();
            _progressIndicator.IsBusy = true;
            _progressIndicator.HorizontalContentAlignment = HorizontalAlignment.Stretch;
            _progressIndicator.VerticalContentAlignment = VerticalAlignment.Stretch;

            // Focus the Silverlight plugin, but only when running in-browser
            if (!Current.IsRunningOutOfBrowser)
            {
                HtmlPage.Plugin.Focus();
            }

            // Let the user now we're trying to authenticate him
            _progressIndicator.BusyContent = ApplicationStrings.BusyIndicatorLoadingUser;

            RootVisual = _progressIndicator;
        }

        private void Application_UnhandledException(object sender, ApplicationUnhandledExceptionEventArgs e)
        {
			// Check for Server-Side Session Timeout Exception
			var dex = e.ExceptionObject as DomainOperationException;
			if ((dex != null) 
				&& (dex.ErrorCode == ErrorCodes.NotAuthenticated || dex.ErrorCode == ErrorCodes.Unauthorized) 
				&& WebContext.Current.User.IsAuthenticated)
			{
				// A server-side timeout has occurred.  Call LoadUser which will automatically 
				//   authenticate if "Remember Me" was checked, or prompt for the user to log on again
				WebContext.Current.Authentication.LoadUser(Application_UserLoaded, null);
				e.Handled = true;
			}

            // If the app is running outside of the debugger then report the exception using
            // a ChildWindow control.
            if (!System.Diagnostics.Debugger.IsAttached)
            {
                // NOTE: This will allow the application to continue running after an exception has been thrown
                // but not handled. 
                // For production applications this error handling should be replaced with something that will 
                // report the error to the website and stop the application.
                e.Handled = true;
                ExceptionDialog dlg = new ExceptionDialog(e.ExceptionObject, "Unhandled Exception");
                dlg.Show();
            }
        }
    }
}